package se.webbzon.boltzmann.effect;

import se.webbzon.boltzmann.game.character.AbstractCharacter;
import se.webbzon.oschi01.worldarea.WorldArea;
import se.webbzon.oschi01.worldobject.WorldObject;

public abstract class CharacterEffect extends WorldObject implements Effect {

	// The character to damage
	private final AbstractCharacter character;
	
	// The startup duration of the effect
	private final int duration;
	
	// The remaining duration of the effect
	private int remaining;
	
	/*============================================================
	Constructors
	============================================================*/
	
	/** Creates a new abstract character effect associated with an
	 * abstract character. The effect will be active during the given
	 * duration (number of steps). If the duration is negative then
	 * the effect will last until termination. **/
	public CharacterEffect(	AbstractCharacter character, 
							int duration) {
		super(WorldObject.onStep);
		this.character = character;
		this.duration = duration;
		remaining = duration;
	}
	
	/*============================================================
	Public Methods
	============================================================*/
	
	/** This method is invoked when the character effect begins. **/
	public abstract void onEffectBegin(WorldArea world);
	
	/** This method is invoked during each character effect step. **/
	public abstract void onEffectStep(WorldArea world);
	
	/** This method is invoked when the character effect ends. **/
	public abstract void onEffectEnd(WorldArea world);
	
	/** Returns the remaining duration of the effect. **/
	public int getDuration() {
		return remaining;
	}
	
	/** Returns the startup duration of the effect. **/
	public int getStartupDuration() {
		return duration;
	}
	
	/** Returns the character associated with this character effect. **/
	public AbstractCharacter getCharacter() {
		return character;
	}
	
	@Override public final void onStep(WorldArea world) {
		if (remaining == 0)
			terminate(world);
		else if (remaining > 0) {
			onEffectStep(world);
			remaining--;
		}
	}

	@Override public final void launch(WorldArea world) {
		world.createInstance(this);
		onEffectBegin(world);
	}
	
	@Override public final void terminate(WorldArea world) {
		onEffectEnd(world);
		world.destroyInstance(this);
	}

}
